package com.eastfair.auth.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.eastfair.annotation.base.SubjectTypeEnum;
import com.eastfair.auth.dao.BusinessUserMapper;
import com.eastfair.auth.dao.UserAccountMapper;
import com.eastfair.auth.dto.UserAccountDto;
import com.eastfair.auth.dto.UserUpdPassParam;
import com.eastfair.auth.entity.*;
import com.eastfair.auth.enumeration.UserAccountStatusEnum;
import com.eastfair.auth.service.AudienceOrganizationService;
import com.eastfair.auth.service.OrganizationService;
import com.eastfair.auth.service.UserAccountService;
import com.eastfair.auth.service.UserOrganizationService;
import com.eastfair.auth.vo.RoleVo;
import com.eastfair.auth.vo.UserAccountVo;
import com.eastfair.boot.service.SuperCacheServiceImpl;
import com.eastfair.businpoint.BusinLoadUserPermissPoint;
import com.eastfair.businpoint.BusinLoadUserRelevancePoint;
import com.eastfair.cache.auth.AccountUserCacheKeyBuilder;
import com.eastfair.cache.repository.CacheOps;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;
import com.eastfair.core.businmodel.DBNameType;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.model.CacheKeyBuilder;
import com.eastfair.core.snowflake.DefaultUidGenerator;
import com.eastfair.core.utils.Base64Util;
import com.eastfair.core.utils.MD5Util;
import com.eastfair.handler.EfTokenHandler;
import com.eastfair.imaster.api.EmployeeServiceFeign;
import com.eastfair.imaster.dto.EmployeeDTO;
import com.eastfair.jwt.model.AuthInfo;
import com.eastfair.jwt.model.JwtUserInfo;
import com.eastfair.jwt.service.JwtService;
import com.eastfair.log.point.PointUtil;
import com.eastfair.projectcore.api.ProjectCoreServiceFeign;
import com.eastfair.projectcore.vo.MenuVO;
import com.eastfair.util.CodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import static com.eastfair.core.exception.code.ExceptionCode.*;

/**
 * <p>
 * 业务实现类
 * 用户账户信息
 * </p>
 *
 * @author ligang
 * @date 2021-07-13
 */
@Slf4j
@Service
@DS("#thread.tenant")
//@DS("#header.tenant")
//@DS("ds-2")
public class UserAccountServiceImpl extends SuperCacheServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {

    @Autowired
    ProjectCoreServiceFeign projectCoreServiceFeign;

    @Autowired
    EmployeeServiceFeign employeeServiceFeign;

    @Autowired
    protected CacheOps cacheOps;

    @Autowired
    OrganizationService organizationService;

    @Autowired
    UserOrganizationService userOrganizationService;

    @Autowired
    JwtService jwtService;

    @Autowired
    EfTokenHandler efTokenHandler;

    @Autowired
    BusinessUserMapper businessUserMapper;

    @Autowired
    AudienceOrganizationService audienceOrganizationService;

    @Autowired
    PointUtil pointUtil;
    /**************sharding 分库分表操作 *****************/
    @Override
    public boolean updateByIdOfShard(UserAccount entity) {
        UpdateWrapper<UserAccount> updateWrapper = new UpdateWrapper<>();
        //可将指定字段更新为null
        updateWrapper.lambda().eq(UserAccount::getProjectId, entity.getProjectId()).eq(UserAccount::getId, entity.getId());
        entity.setProjectId(null);
        //删除缓存
        delCache(entity);
        return SqlHelper.retBool(this.getBaseMapper().update(entity, updateWrapper));
    }

    /**
     * 处理新增相关处理
     *
     * @param model 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerSave(UserAccount model) {
        if (StringUtils.isBlank(model.getName())) {
            //空，随机给登录名
            String name = nonredundantUser();
            model.setName(name);
        }
        return R.successDef();
    }

    /**
     * 获取不重复的10位数字
     *
     * @return
     */
    public String nonredundantUser() {
        String name = "";
        for (int n = 0; n < 10; n++) {
            name += (int) (10 * (Math.random()));
        }
        //是否重复
        int num = queryCodeSize(name);
        if (num > 0) {
            nonredundantUser();
        }
        return name;
    }

    public static void main(String[] args) {
        String name = "";
        for (int n = 0; n < 10; n++) {
            name += (int) (10 * (Math.random()));
        }
        System.out.println(name);
    }
    public int queryCodeSize(String name) {
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(name)) {
            queryWrapper.lambda().eq(UserAccount::getName, name);
        }
        queryWrapper.lambda().eq(UserAccount::getIsDeleted, BusinessConstant.DELETE_NO);
        return count(queryWrapper);
    }

    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<UserAccount> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    protected CacheKeyBuilder cacheKeyBuilder() {
        return new AccountUserCacheKeyBuilder();
    }

    @Override
    public UserAccount getUser(UserAccount userAccount) {
        List<UserAccount> userAccountList = listOfUserAccount(userAccount, null);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            return userAccountList.get(0);
        }
        return null;
    }

    @Override
    public R<UserAccountVo> register(UserAccountDto userAccountDto) {
        //登录名不能重复
        if (userAccountDto.getProjectId() == null) {
            //项目id不能为空
            return R.fail(PROJECT_ID_ERROR);
        }
        //查询用户是否存在
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        if (userAccountDto.getProjectId() != null) {
            queryWrapper.lambda().eq(UserAccount::getProjectId, userAccountDto.getProjectId());
        }
        queryWrapper.lambda().eq(UserAccount::getIsDeleted, BusinessConstant.DELETE_NO);
        if (userAccountDto != null) {
            queryWrapper.and(wrapper -> {
                if (StringUtils.isNotBlank(userAccountDto.getEmail())) {
                    wrapper.eq("email", userAccountDto.getEmail());
                    wrapper.or();
                }
                if (StringUtils.isNotBlank(userAccountDto.getMobile())) {
                    wrapper.eq("mobile", userAccountDto.getMobile());
                }
            });
        }
        //查询用户
        List<UserAccount> userAccountList = list(queryWrapper);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            return R.fail(LOGINNAME_AGAIN);
        }
        UserAccount saveUserAccount = BeanUtil.toBean(userAccountDto, getEntityClass());
        saveUserAccount.setId(DefaultUidGenerator.getUidOfProjectId(userAccountDto.getProjectId() == null ? 0L : userAccountDto.getProjectId()));
        saveUserAccount.setProjectId(userAccountDto.getProjectId());
        saveUserAccount.setStatus(UserAccountStatusEnum.NORMAL);
        saveUserAccount.setPassword(StringUtils.isNotBlank(saveUserAccount.getPassword()) ? getStorePassword(saveUserAccount.getPassword()) : null);
//        saveUserAccount.setPassword(getStorePassword(StringUtils.isNotBlank(saveUserAccount.getPassword()) ? saveUserAccount.getPassword() : BusinessConstant.initPassword));
        //默认游客
        saveUserAccount.setIsTourist(BusinessConstant.YES);
        save(saveUserAccount);
        UserAccountVo userAccountVo = doToVo(saveUserAccount);
        //加载token信息
        loadToken(userAccountVo, userAccountDto);
        return R.success(userAccountVo);
    }

    @Override
    public R<UserAccountVo> registerOfCompany(UserAccountDto userAccountDto) {
        //登录名不能重复
        if (userAccountDto.getProjectId() == null) {
            //项目id不能为空
            return R.fail(PROJECT_ID_ERROR);
        }
        //查询用户是否存在
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        if (userAccountDto.getProjectId() != null) {
            queryWrapper.lambda().eq(UserAccount::getProjectId, userAccountDto.getProjectId());
        }
        queryWrapper.lambda().eq(UserAccount::getIsDeleted, BusinessConstant.DELETE_NO);
        if (userAccountDto != null) {
            queryWrapper.and(wrapper -> {
                if (StringUtils.isNotBlank(userAccountDto.getEmail())) {
                    wrapper.eq("email", userAccountDto.getEmail());
                    wrapper.or();
                }
                if (StringUtils.isNotBlank(userAccountDto.getMobile())) {
                    wrapper.eq("mobile", userAccountDto.getMobile());
                }
            });
        }
        //查询用户
        List<UserAccount> userAccountList = list(queryWrapper);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            return R.fail(LOGINNAME_AGAIN);
        }
        UserAccount saveUserAccount = BeanUtil.toBean(userAccountDto, getEntityClass());
        saveUserAccount.setId(DefaultUidGenerator.getUidOfProjectId(userAccountDto.getProjectId() == null ? 0L : userAccountDto.getProjectId()));
        saveUserAccount.setProjectId(userAccountDto.getProjectId());
        saveUserAccount.setStatus(UserAccountStatusEnum.NORMAL);
        saveUserAccount.setPassword(StringUtils.isNotBlank(saveUserAccount.getPassword()) ? getStorePassword(saveUserAccount.getPassword()) : null);
        //默认游客
        saveUserAccount.setIsTourist(BusinessConstant.YES);
        saveUserAccount.setCompanyId(userAccountDto.getCompanyId());
        saveUserAccount.setIsEmployee(BusinessConstant.YES);
        save(saveUserAccount);
        UserAccountVo userAccountVo = doToVo(saveUserAccount);
        //公司拉入员工
        EmployeeDTO employeeDTO = new EmployeeDTO();
        employeeDTO.setCompanyId(userAccountVo.getCompanyId());
        employeeDTO.setUserAccountId(userAccountVo.getId());
        employeeDTO.setIsAdmin(BusinessConstant.YES);
        employeeDTO.setNickName(userAccountVo.getNickName());
        return employeeServiceFeign.addUserIdOfCompany(employeeDTO);
    }

    @Override
    @InterceptorIgnore(tenantLine = "true")
    public R<UserAccountVo> login(UserAccountDto userAccountDto) {
        UserAccount queryUserAccount = new UserAccount();
        BeanUtils.copyProperties(userAccountDto, queryUserAccount);
        if (ContextUtil.getProjectId() != null) {
            queryUserAccount.setProjectId(ContextUtil.getProjectId());
        }
        //查询用户
        UserAccount resultUserAccount = getUser(queryUserAccount);
        if (resultUserAccount != null) {
            if (UserAccountStatusEnum.NORMAL.eq(resultUserAccount.getStatus())) {
                if (!isValidPassword(userAccountDto.getPassword(), resultUserAccount.getPassword())) {
                    //密码错误
                    return R.fail(JWT_USER_INVALID);
                }
                return R.success(assemblyUserAccount(resultUserAccount, userAccountDto));

            } else if (UserAccountStatusEnum.DELETE.eq(resultUserAccount.getStatus())) {
                //用户不存在
                return R.fail(USER_NO_ERROR);
            }
        }
        return R.fail(USER_NO_ERROR);
    }

    @Override
    public R<UserAccountVo> loginOfMobile(UserAccountDto userAccountDto) {
        UserAccount queryUserAccount = new UserAccount();
        if (ContextUtil.getProjectId() != null) {
            queryUserAccount.setProjectId(ContextUtil.getProjectId());
        }
        queryUserAccount.setMobile(userAccountDto.getMobile());
        //查询用户
        UserAccount resultUserAccount = getUser(queryUserAccount);
        if (resultUserAccount != null) {
            if (UserAccountStatusEnum.NORMAL.eq(resultUserAccount.getStatus())) {
                return R.success(assemblyUserAccount(resultUserAccount, userAccountDto));
            } else if (UserAccountStatusEnum.DELETE.eq(resultUserAccount.getStatus())) {
                //用户不存在
                return R.fail(USER_NO_ERROR);
            }
        }
        return R.fail(USER_NO_ERROR);
    }

    @Override
    public R<UserAccountVo> loginOfEmail(UserAccountDto userAccountDto) {
        UserAccount queryUserAccount = new UserAccount();
        if (ContextUtil.getProjectId() != null) {
            queryUserAccount.setProjectId(ContextUtil.getProjectId());
        }
        queryUserAccount.setEmail(userAccountDto.getEmail());
        //查询用户
        UserAccount resultUserAccount = getUser(queryUserAccount);
        if (resultUserAccount != null) {
            if (UserAccountStatusEnum.NORMAL.eq(resultUserAccount.getStatus())) {
                return R.success(assemblyUserAccount(resultUserAccount, userAccountDto));
            } else if (UserAccountStatusEnum.DELETE.eq(resultUserAccount.getStatus())) {
                //用户不存在
                return R.fail(USER_NO_ERROR);
            }
        }
        return R.fail(USER_NO_ERROR);
    }

    public UserAccountVo assemblyUserAccount(UserAccount resultUserAccount, UserAccountDto userAccountDto) {
        if (resultUserAccount != null) {
            UserAccountVo userAccountVo = doToVo(resultUserAccount);
            ContextUtil.setProjectId(resultUserAccount.getProjectId());
            //加载用户角色信息
            loadUserRole(userAccountVo);
            //加载token信息
            loadToken(userAccountVo, userAccountDto);
            //加载业务事件
            loadBusiness(userAccountVo);
            //更新最新token
            efTokenHandler.addToken(userAccountVo.getAuthInfo().getToken(), ContextUtil.getTerminalType(), userAccountVo.getId());
            //添加到事件监听队列
            BusinLoadUserPermissPoint businLoadUserPermissPoint = new BusinLoadUserPermissPoint();
            businLoadUserPermissPoint.setUserIdList(Arrays.asList(resultUserAccount.getId()));
            businLoadUserPermissPoint.setProjectId(ContextUtil.getProjectId());
            pointUtil.addBusinPointMsg(businLoadUserPermissPoint);


            return userAccountVo;
        }
        return null;
    }

    @Override
    public R loginOut(Long userId) {
        return R.success();
    }


    /**
     * 加载用户角色信息
     *
     * @param userAccountVo
     */
    public void loadUserRole(UserAccountVo userAccountVo) {
        UserOrganization userOrganization = new UserOrganization();
        userOrganization.setUserId(userAccountVo.getId());
        List<UserOrganization> userOrganizationList = userOrganizationService.listOfUserOrganization(userOrganization, null, null);
        if (userOrganizationList != null && !userOrganizationList.isEmpty()) {
            //将角色加载进去
            List<Long> orgIds = userOrganizationList.stream().map(UserOrganization::getOrganizationId).collect(Collectors.toList());
            List<RoleVo> roleVoList = organizationService.loadRole(orgIds);
            userAccountVo.setRoleVoList(roleVoList);
            List<MenuVO> menuVOList = organizationService.loadMenu(roleVoList);
            userAccountVo.setMenuVOList(menuVOList);
            userAccountVo.setPermissionList(organizationService.loadMenuPermission(roleVoList));
            userAccountVo.setFunctionVOList(organizationService.loadFunction(roleVoList));
        }

    }

    public void loadToken(UserAccountVo userAccountVo, UserAccountDto userAccountDto) {
        JwtUserInfo jwtUserInfo = new JwtUserInfo();
        jwtUserInfo.setProjectId(ContextUtil.getProjectId());
        jwtUserInfo.setUserId(userAccountVo.getId());
        jwtUserInfo.setName(userAccountVo.getName());
        if (userAccountDto.getSubjectType() != null) {
            jwtUserInfo.setSubjectType(userAccountDto.getSubjectType().getCode());
        }
        AuthInfo authInfo = jwtService.build(jwtUserInfo);
        userAccountVo.setAuthInfo(authInfo);
    }

    /**
     * 加载业务事件
     *
     * @param userAccountVo
     */
    public void loadBusiness(UserAccountVo userAccountVo) {
        // TODO: 2021/7/28 业务事件在这添加
    }

    public String getStorePassword(String password) {
        return new String(Base64Util.base64Encrypt(MD5Util.getMD5String(password)));
    }

    @Override
    public boolean isValidPassword(String password, String storePassword) {
        String basePassword = new String(Base64Util.base64Encrypt(MD5Util.getMD5String(password)));
        return basePassword.equals(storePassword);
    }

    @Override
    public List<UserAccount> getUserByNameAllDb(UserAccountDto userAccountDto) {
        DBNameType[] dbNameTypes = DBNameType.values();
        for (DBNameType dbNameType : dbNameTypes) {
            ContextUtil.setTenant(dbNameType.getDbName());
            List<UserAccount> userAccountList = businessUserMapper.getUserByName(userAccountDto);
            if (userAccountList != null && !userAccountList.isEmpty()) {
                return userAccountList;
            }
        }
        return null;
    }

    @Override
    public List<UserAccount> listOfPhoneOrEmail(UserAccountDto userAccountDto) {
        //查询用户是否存在
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserAccount::getIsDeleted, BusinessConstant.DELETE_NO);
        if (userAccountDto != null) {
            queryWrapper.and(wrapper -> {
                if (StringUtils.isNotBlank(userAccountDto.getEmail())) {
                    wrapper.eq("email", userAccountDto.getEmail());
                    wrapper.or();
                }
                if (StringUtils.isNotBlank(userAccountDto.getMobile())) {
                    wrapper.eq("mobile", userAccountDto.getMobile());
                }
            });
        }
        //查询用户
        List<UserAccount> userAccountList = list(queryWrapper);
        return userAccountList;
    }

    @Override
    public R<Boolean> updPassword(UserUpdPassParam userUpdPassParam) {
        UserAccount queryUserAccount = new UserAccount();
        if (ContextUtil.getProjectId() != null) {
            queryUserAccount.setProjectId(ContextUtil.getProjectId());
        }
        queryUserAccount.setId(userUpdPassParam.getId());
        //查询用户
        UserAccount resultUserAccount = getUser(queryUserAccount);
        if (resultUserAccount != null) {
            //密码是否正确
            if (isValidPassword(userUpdPassParam.getOldPassword(), resultUserAccount.getPassword())) {
                resultUserAccount.setPassword(getStorePassword(userUpdPassParam.getNewPassword()));
            }
            //更新密码
            updateByIdOfShard(resultUserAccount);
        }
        return R.success(true);
    }

    @Override
    public R<Boolean> setPassword(UserUpdPassParam userUpdPassParam) {
        //查询用户
        UserAccount resultUserAccount = getById(userUpdPassParam.getId());
        if (resultUserAccount != null) {
            resultUserAccount.setPassword(getStorePassword(userUpdPassParam.getNewPassword()));
            //更新密码
            updateById(resultUserAccount);
        }
        return R.success(true);
    }

    @Override
    public R<Boolean> initPassword(Long userId) {
        UserAccount queryUserAccount = new UserAccount();
        if (ContextUtil.getProjectId() != null) {
            queryUserAccount.setProjectId(ContextUtil.getProjectId());
        }
        queryUserAccount.setId(userId);
        //查询用户
        UserAccount resultUserAccount = getUser(queryUserAccount);
        if (resultUserAccount != null) {
            resultUserAccount.setPassword(getStorePassword(BusinessConstant.initPassword));
            //更新初始化密码
            updateByIdOfShard(resultUserAccount);
        }
        return R.success(true);
    }

    @Override
    public R<UserAccountVo> initRole(UserAccountDto userAccountDto) {
        UserAccount userAccount = getById(userAccountDto.getId());
        if (userAccount != null) {
            if (userAccountDto.getIsVisitor() == BusinessConstant.YES) {
                userAccount.setIsVisitor(BusinessConstant.YES);
                userAccount.setIsTourist(BusinessConstant.NO);
                userAccount.setIsCompleteInfo(userAccountDto.getIsCompleteInfo());
                userAccount.setIsCompleteQuestion(userAccountDto.getIsCompleteQuestion());
                //添加到观众组
                audienceOrganizationService.addUserOfAudience(ContextUtil.getProjectId(), Arrays.asList(userAccountDto.getId()));
            } else if (userAccountDto.getIsEmployee() == BusinessConstant.YES) {
                userAccount.setIsEmployee(BusinessConstant.YES);
                userAccount.setIsTourist(BusinessConstant.NO);
            }
            updateById(userAccount);
        }
        return null;
    }

    @Override
    public R<List<UserAccountVo>> findByIds(List<Long> userIds) {
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .in(UserAccount::getId, userIds)
                .eq(UserAccount::getStatus, UserAccountStatusEnum.NORMAL);
        List<UserAccount> userAccountList = list(queryWrapper);
        return R.success(doToVos(userAccountList));
    }

    @Override
    public R<UserAccountVo> findById(Long userId) {
        if (userId == null || userId == 0) {
            return R.fail("获取用户失败");
        }
        UserAccount userAccount = new UserAccount();
        userAccount.setId(userId);
        userAccount = getUser(userAccount);
        UserAccountVo userAccountVo = doToVo(userAccount);
        //加载用户角色信息
        loadUserRole(userAccountVo);
        userAccountVo.setSubjectType(SubjectTypeEnum.get(ContextUtil.getSubjectType()));
        return R.success(userAccountVo);
    }


//    @Override
//    public List<UserAccount> findRoleOfUserId(Long userId) {
//        return null;
//    }


    @Override
    public List<UserAccount> listOfUserAccount(UserAccount userAccount, List<Long> ids) {
        //查询
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        if (userAccount != null) {
            if (userAccount.getId() != null) {
                queryWrapper.lambda().eq(UserAccount::getId, userAccount.getId());
            }
            if (StringUtils.isNotBlank(userAccount.getEmail())) {
                queryWrapper.lambda().eq(UserAccount::getEmail, userAccount.getEmail());
            }
            if (StringUtils.isNotBlank(userAccount.getMobile())) {
                queryWrapper.lambda().eq(UserAccount::getMobile, userAccount.getMobile());
            }
            if (StringUtils.isNotBlank(userAccount.getName())) {
                queryWrapper.lambda().eq(UserAccount::getName, userAccount.getName());
            }
        }
        if (userAccount != null && userAccount.getProjectId() != null) {
            queryWrapper.lambda().eq(UserAccount::getProjectId, userAccount.getProjectId());
        } else if (ContextUtil.getProjectId() != null) {
            queryWrapper.lambda().eq(UserAccount::getProjectId, ContextUtil.getProjectId());
        }
        if (ids != null && !ids.isEmpty()) {
            queryWrapper.lambda().in(UserAccount::getId, ids);
        }
        queryWrapper.lambda().eq(UserAccount::getIsDeleted, BusinessConstant.DELETE_NO);
        List<UserAccount> userAccountList = list(queryWrapper);
        return userAccountList;
    }

    @Override
    public List<UserAccountVo> listOfUserAccountVo(UserAccount userAccount, List<Long> ids) {
        List<UserAccount> userAccountList = listOfUserAccount(userAccount, ids);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            return doToVos(userAccountList);
        }
        return null;
    }

    @Override
    public UserAccountVo findOrgRoleOfUserId(Long userId) {
        UserAccount queryUserAccount = new UserAccount();
        queryUserAccount.setId(userId);
        queryUserAccount.setStatus(UserAccountStatusEnum.NORMAL);
        UserAccount resultUserAccount = getUser(queryUserAccount);
        if (resultUserAccount != null) {
            UserAccountVo userAccountVo = doToVo(resultUserAccount);
            //加载用户角色信息
            loadUserRole(userAccountVo);
            return userAccountVo;
        }
        return null;
    }

    @Override
    public R verifyMenu(Long userId, List<Long> menuIds) {
        //查询用户所拥有的菜单信息
        UserOrganization userOrganization = new UserOrganization();
        userOrganization.setUserId(userId);
        List<UserOrganization> userOrganizationList = userOrganizationService.listOfUserOrganization(userOrganization, null, null);
        if (userOrganizationList != null && !userOrganizationList.isEmpty()) {
            //查询组织信息
            List<Long> orgIds = userOrganizationList.stream().map(UserOrganization::getOrganizationId).collect(Collectors.toList());
            List<RoleVo> roleVoList = organizationService.loadRole(orgIds);
            //查询角色菜单关联信息
            List<MenuRole> menuRoleList = organizationService.loadMenuRole(roleVoList);
            //校验菜单是否超出范围
            if (menuRoleList != null && !menuRoleList.isEmpty()) {
                List<Long> userMenuIds = menuRoleList.stream().map(MenuRole::getMenuId).collect(Collectors.toList());
                for (Long menuId : menuIds) {
                    if (!userMenuIds.contains(menuId)) {
                        //菜单超出范围
                        return R.fail(MEUN_MORE);
                    }
                }
                return R.success();
            }
        }
        //菜单超出范围
        return R.fail(MEUN_MORE);
    }

    @Override
    public R verifyFunction(Long userId, List<Long> functionIds) {
        //查询用户所拥有的菜单信息
        UserOrganization userOrganization = new UserOrganization();
        userOrganization.setUserId(userId);
        List<UserOrganization> userOrganizationList = userOrganizationService.listOfUserOrganization(userOrganization, null, null);
        if (userOrganizationList != null && !userOrganizationList.isEmpty()) {
            //查询组织信息
            List<Long> orgIds = userOrganizationList.stream().map(UserOrganization::getOrganizationId).collect(Collectors.toList());
            List<RoleVo> roleVoList = organizationService.loadRole(orgIds);
            //查询角色菜单关联信息
            List<FunctionRole> functionRoleList = organizationService.loadFunctionRole(roleVoList);
            if (functionRoleList != null && !functionRoleList.isEmpty()) {
                List<Long> userFunctionIds = functionRoleList.stream().map(FunctionRole::getFunctionId).collect(Collectors.toList());
                for (Long menuId : functionIds) {
                    if (!userFunctionIds.contains(menuId)) {
                        //事件超出范围
                        return R.fail(MEUN_MORE);
                    }
                }
                return R.success();
            }
        }
        //事件超出范围
        return R.fail(MEUN_MORE);
    }

    @Override
    public R removeByIdsOfLogicOfSharding(List<Long> ids) {
        List<UserAccount> userAccountList = listByIds(ids);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            for (UserAccount userAccount : userAccountList) {
                userAccount.setIsDeleted(BusinessConstant.DELETE_YES);
                updateByIdOfShard(userAccount);
            }
        }
        return R.success();
    }


    @Override
    public R<Boolean> updateById(UserAccountDto userAccountDto) {
        UserAccount userAccount = getById(userAccountDto.getId());
        if (userAccount == null) {
            return R.fail("修改失败");
        }
        if(StringUtils.isNotBlank(userAccountDto.getEmail())){
            userAccount.setEmail(userAccountDto.getEmail());
        }
        if(StringUtils.isNotBlank(userAccountDto.getName())){
            userAccount.setName(userAccountDto.getName());
        }
        if(StringUtils.isNotBlank(userAccountDto.getMobile())){
            userAccount.setMobile(userAccountDto.getMobile());
        }
        userAccount.setHeadImg(userAccountDto.getHeadImg());
        userAccount.setNickName(userAccountDto.getNickName());
        return R.success(updateByIdOfShard(userAccount));
    }

    @Override
    public R<Boolean> updateByIdOfCompany(UserAccountDto userAccountDto) {
        UserAccount userAccount = getById(userAccountDto.getId());
        if (userAccount == null) {
            return R.fail("修改失败");
        }
        if(StringUtils.isNotBlank(userAccountDto.getEmail())){
            userAccount.setEmail(userAccountDto.getEmail());
        }
        if(StringUtils.isNotBlank(userAccountDto.getName())){
            userAccount.setName(userAccountDto.getName());
        }
        if(StringUtils.isNotBlank(userAccountDto.getMobile())){
            userAccount.setMobile(userAccountDto.getMobile());
        }
        userAccount.setHeadImg(userAccountDto.getHeadImg());
        userAccount.setNickName(userAccountDto.getNickName());
//        //修改公司用户
//        EmployeeDTO employeeDTO = new EmployeeDTO();
//        employeeDTO.setUserAccountId(userAccountDto.getId());
//        employeeDTO.setNickName(userAccountDto.getNickName());
//        employeeServiceFeign.updateCompanyUser(employeeDTO);
        return R.success(updateByIdOfShard(userAccount));
    }

    @Override
    public R<UserAccountVo> addAdminUser(UserAccountDto userAccountDto) {
        if (userAccountDto.getProjectId() == null) {
            //项目id不能为空
            return R.fail(PROJECT_ID_ERROR);
        }
        if (StringUtils.isBlank(userAccountDto.getName())) {
            //随机取name
            userAccountDto.setName(randomName(userAccountDto));
        }
        //查询用户是否存在，存在则更新
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        if (userAccountDto.getProjectId() != null) {
            queryWrapper.lambda().eq(UserAccount::getProjectId, userAccountDto.getProjectId());
        }
        queryWrapper.lambda().eq(UserAccount::getIsDeleted, BusinessConstant.DELETE_NO);
        if (userAccountDto != null && (StringUtils.isNotBlank(userAccountDto.getEmail()) || StringUtils.isNotBlank(userAccountDto.getMobile()))) {
            queryWrapper.and(wrapper -> {
                if (StringUtils.isNotBlank(userAccountDto.getEmail())) {
                    wrapper.eq("email", userAccountDto.getEmail());
                    wrapper.or();
                }
                if (StringUtils.isNotBlank(userAccountDto.getMobile())) {
                    wrapper.eq("mobile", userAccountDto.getMobile());
                }
            });
        }
        //查询用户
        log.info(ContextUtil.getTenant());
        List<UserAccount> userAccountList = list(queryWrapper);
        if (userAccountList != null && !userAccountList.isEmpty()) {
            UserAccount userAccount = userAccountList.get(0);
            //修改
            userAccount.setName(userAccountDto.getName());
            userAccount.setMobile(userAccountDto.getMobile());
            userAccount.setEmail(userAccountDto.getEmail());
            updateById(userAccount);
            return R.success(doToVo(userAccount));
        } else {
            UserAccount saveUserAccount = BeanUtil.toBean(userAccountDto, getEntityClass());
            saveUserAccount.setId(DefaultUidGenerator.getUidOfProjectId(userAccountDto.getProjectId() == null ? 0L : userAccountDto.getProjectId()));
            saveUserAccount.setProjectId(userAccountDto.getProjectId());
            saveUserAccount.setStatus(UserAccountStatusEnum.NORMAL);
            saveUserAccount.setPassword(getStorePassword(BusinessConstant.initPassword));
            save(saveUserAccount);
            return R.success(doToVo(saveUserAccount));
        }

    }

    public String randomName(UserAccountDto userAccountDto) {
        String name = "admin" + (new Random().nextInt(100000) + 100000);
        //查询用户是否存在
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        if (userAccountDto.getProjectId() != null) {
            queryWrapper.lambda().eq(UserAccount::getProjectId, userAccountDto.getProjectId());
        }
        queryWrapper.lambda().eq(UserAccount::getName, name);
        queryWrapper.lambda().eq(UserAccount::getIsDeleted, BusinessConstant.DELETE_NO);
        //查询用户
        int i = count(queryWrapper);
        if (i > 0) {
            return randomName(userAccountDto);
        }
        return name;
    }

    public UserAccountVo doToVo(UserAccount userAccount) {
        UserAccountVo userAccountVo = new UserAccountVo();
        BeanUtils.copyProperties(userAccount, userAccountVo);
        userAccountVo.setId(userAccount.getId());
        userAccountVo.setIsSetPassword(StringUtils.isNotBlank(userAccount.getPassword()) ? BusinessConstant.YES : BusinessConstant.NO);
        return userAccountVo;
    }

    public List<UserAccountVo> doToVos(List<UserAccount> userAccountList) {
        if (userAccountList == null || userAccountList.isEmpty()) {
            return null;
        }
        List<UserAccountVo> result = new ArrayList<>();
        for (UserAccount userAccount : userAccountList) {
            result.add(doToVo(userAccount));
        }
        return result;
    }
}
